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

Side by Side Diff: client/prune_crash_reports.cc

Issue 1392653002: Add functionality to prune old crash reports from the database. (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 5 years, 2 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 unified diff | Download patch
« no previous file with comments | « client/prune_crash_reports.h ('k') | client/prune_crash_reports_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "client/prune_crash_reports.h"
16
17 #include <sys/stat.h>
18
19 #include <algorithm>
20 #include <vector>
21
22 #include "base/logging.h"
23
24 namespace crashpad {
25
26 void PruneCrashReportDatabase(CrashReportDatabase* database,
27 PruneCondition* condition) {
28 std::vector<CrashReportDatabase::Report> all_reports;
29 CrashReportDatabase::OperationStatus status;
30
31 status = database->GetPendingReports(&all_reports);
32 if (status != CrashReportDatabase::kNoError) {
33 LOG(ERROR) << "PruneCrashReportDatabase: Failed to get pending reports";
34 return;
35 }
36
37 std::vector<CrashReportDatabase::Report> completed_reports;
38 status = database->GetCompletedReports(&completed_reports);
39 if (status != CrashReportDatabase::kNoError) {
40 LOG(ERROR) << "PruneCrashReportDatabase: Failed to get completed reports";
41 return;
42 }
43 all_reports.insert(all_reports.end(), completed_reports.begin(),
44 completed_reports.end());
45
46 std::sort(all_reports.begin(), all_reports.end(),
47 [](const CrashReportDatabase::Report& lhs,
48 const CrashReportDatabase::Report& rhs) {
49 return lhs.creation_time > rhs.creation_time;
50 });
51
52 for (const auto& report : all_reports) {
53 if (condition->ShouldPruneReport(report)) {
54 status = database->DeleteReport(report.uuid);
55 if (status != CrashReportDatabase::kNoError) {
56 LOG(ERROR) << "Database Pruning: Failed to remove report "
57 << report.uuid.ToString();
58 }
59 }
60 }
61
62 // TODO(rsesek): For databases that do not use a directory structure,
63 // it is possible for the metadata sidecar to become corrupted and thus
64 // leave orphaned crash report files on-disk.
65 // https://code.google.com/p/crashpad/issues/detail?id=66
66 }
67
68 // static
69 scoped_ptr<PruneCondition> PruneCondition::GetDefault() {
70 // DatabaseSizePruneCondition must be the LHS so that it is always evaluated,
71 // due to the short-circuting behavior of BinaryPruneCondition.
72 return make_scoped_ptr(new BinaryPruneCondition(BinaryPruneCondition::OR,
73 new DatabaseSizePruneCondition(1024 * 128), new AgePruneCondition(365)));
74 }
75
76 static const time_t kSecondsInDay = 60 * 60 * 24;
77
78 AgePruneCondition::AgePruneCondition(int max_age_in_days)
79 : oldest_report_time_(
80 ((time(nullptr) - (max_age_in_days * kSecondsInDay))
81 / kSecondsInDay) * kSecondsInDay) {}
82
83 AgePruneCondition::~AgePruneCondition() {}
84
85 bool AgePruneCondition::ShouldPruneReport(
86 const CrashReportDatabase::Report& report) {
87 return report.creation_time < oldest_report_time_;
88 }
89
90 DatabaseSizePruneCondition::DatabaseSizePruneCondition(size_t max_size_in_kb)
91 : max_size_in_kb_(max_size_in_kb), measured_size_in_kb_(0) {}
92
93 DatabaseSizePruneCondition::~DatabaseSizePruneCondition() {}
94
95 bool DatabaseSizePruneCondition::ShouldPruneReport(
96 const CrashReportDatabase::Report& report) {
97 #if defined(OS_POSIX)
98 struct stat statbuf;
99 if (stat(report.file_path.value().c_str(), &statbuf) == 0) {
100 #elif defined(OS_WIN)
101 struct _stati64 statbuf;
102 if (_wstat64(report.file_path.value().c_str(), &statbuf) == 0) {
103 #else
104 #error "Not implemented"
105 #endif
106 // Round up fractional KB to the next 1-KB boundary.
107 measured_size_in_kb_ +=
108 static_cast<size_t>((statbuf.st_size + 1023) / 1024);
109 }
110 return measured_size_in_kb_ > max_size_in_kb_;
111 }
112
113 BinaryPruneCondition::BinaryPruneCondition(
114 Operator op, PruneCondition* lhs, PruneCondition* rhs)
115 : op_(op), lhs_(lhs), rhs_(rhs) {}
116
117 BinaryPruneCondition::~BinaryPruneCondition() {}
118
119 bool BinaryPruneCondition::ShouldPruneReport(
120 const CrashReportDatabase::Report& report) {
121 switch (op_) {
122 case AND:
123 return lhs_->ShouldPruneReport(report) && rhs_->ShouldPruneReport(report);
124 case OR:
125 return lhs_->ShouldPruneReport(report) || rhs_->ShouldPruneReport(report);
126 default:
127 NOTREACHED();
128 return false;
129 }
130 }
131
132 } // namespace crashpad
OLDNEW
« no previous file with comments | « client/prune_crash_reports.h ('k') | client/prune_crash_reports_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698