OLD | NEW |
---|---|
(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 } | |
Mark Mentovai
2015/10/07 20:58:23
Lose a TODO, gain a TODO. Can you leave behind a b
Robert Sesek
2015/10/07 21:01:34
Done.
| |
62 | |
63 // static | |
64 scoped_ptr<PruneCondition> PruneCondition::GetDefault() { | |
65 // DatabaseSizePruneCondition must be the LHS so that it is always evaluated, | |
66 // due to the short-circuting behavior of BinaryPruneCondition. | |
67 return make_scoped_ptr(new BinaryPruneCondition(BinaryPruneCondition::OR, | |
68 new DatabaseSizePruneCondition(1024 * 128), new AgePruneCondition(365))); | |
69 } | |
70 | |
71 static const time_t kSecondsInDay = 60 * 60 * 24; | |
72 | |
73 AgePruneCondition::AgePruneCondition(int max_age_in_days) | |
74 : oldest_report_time_( | |
75 ((time(nullptr) - (max_age_in_days * kSecondsInDay)) | |
76 / kSecondsInDay) * kSecondsInDay) {} | |
77 | |
78 AgePruneCondition::~AgePruneCondition() {} | |
79 | |
80 bool AgePruneCondition::ShouldPruneReport( | |
81 const CrashReportDatabase::Report& report) { | |
82 return report.creation_time < oldest_report_time_; | |
83 } | |
84 | |
85 DatabaseSizePruneCondition::DatabaseSizePruneCondition(size_t max_size_in_kb) | |
86 : max_size_in_kb_(max_size_in_kb), measured_size_in_kb_(0) {} | |
87 | |
88 DatabaseSizePruneCondition::~DatabaseSizePruneCondition() {} | |
89 | |
90 bool DatabaseSizePruneCondition::ShouldPruneReport( | |
91 const CrashReportDatabase::Report& report) { | |
92 #if defined(OS_POSIX) | |
93 struct stat statbuf; | |
94 if (stat(report.file_path.value().c_str(), &statbuf) == 0) { | |
95 #elif defined(OS_WIN) | |
96 struct _stati64 statbuf; | |
97 if (_wstat64(report.file_path.value().c_str(), &statbuf) == 0) { | |
98 #else | |
99 #error "Not implemented" | |
100 #endif | |
101 // Round up fractional KB to the next 1-KB boundary. | |
102 measured_size_in_kb_ += | |
103 (static_cast<size_t>(statbuf.st_size) + 1023) / 1024; | |
Mark Mentovai
2015/10/07 20:58:23
size_t may be narrower than decltype(statbuf.st_si
Robert Sesek
2015/10/07 21:01:34
Done.
| |
104 } | |
105 return measured_size_in_kb_ > max_size_in_kb_; | |
106 } | |
107 | |
108 BinaryPruneCondition::BinaryPruneCondition( | |
109 Operator op, PruneCondition* lhs, PruneCondition* rhs) | |
110 : op_(op), lhs_(lhs), rhs_(rhs) {} | |
111 | |
112 BinaryPruneCondition::~BinaryPruneCondition() {} | |
113 | |
114 bool BinaryPruneCondition::ShouldPruneReport( | |
115 const CrashReportDatabase::Report& report) { | |
116 switch (op_) { | |
117 case AND: | |
118 return lhs_->ShouldPruneReport(report) && rhs_->ShouldPruneReport(report); | |
119 case OR: | |
120 return lhs_->ShouldPruneReport(report) || rhs_->ShouldPruneReport(report); | |
121 default: | |
122 NOTREACHED(); | |
123 return false; | |
124 } | |
125 } | |
126 | |
127 } // namespace crashpad | |
OLD | NEW |