1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_TRACING_TRACE_REPORT_TRACE_REPORT_DATABASE_H_
#define CONTENT_BROWSER_TRACING_TRACE_REPORT_TRACE_REPORT_DATABASE_H_
#include <optional>
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/sequence_checker.h"
#include "base/time/time.h"
#include "base/token.h"
#include "content/common/content_export.h"
#include "sql/database.h"
#include "sql/statement.h"
#include "sql/transaction.h"
namespace content {
enum class ReportUploadState {
kNotUploaded = 0,
kPending,
kPending_UserRequested,
kUploaded
};
enum class SkipUploadReason {
kNoSkip = 0,
kSizeLimitExceeded = 1,
kNotAnonymized = 2,
kScenarioQuotaExceeded = 3,
kUploadTimedOut = 4,
kLocalScenario = 5,
};
// BaseTraceReport contains common data used to create and display a trace
// report.
struct CONTENT_EXPORT BaseTraceReport {
BaseTraceReport();
BaseTraceReport(const BaseTraceReport& other);
~BaseTraceReport();
// A unique identifier by which this report will always be known to the
// database as well as outside of it (e.g.: perfetto).
base::Token uuid;
// The time at which the report was created.
base::Time creation_time;
// The name of the scenario that triggered this trace to be collected and
// report to be created.
std::string scenario_name;
// The upload rule name that triggered this report.
std::string upload_rule_name;
// The upload rule value that triggered this report.
std::optional<int32_t> upload_rule_value;
// The total size in bytes taken by the report.
uint64_t total_size = 0;
// The reason for which a report was not uploaded even if the upload rules
// were met.
SkipUploadReason skip_reason = SkipUploadReason::kNoSkip;
};
// NewTraceReport represents the metadata needed to create and add a new
// report into the TraceReportDatabase.
struct CONTENT_EXPORT NewTraceReport : BaseTraceReport {
NewTraceReport();
// NOLINTNEXTLINE(google-explicit-constructor)
NewTraceReport(const BaseTraceReport& report) : BaseTraceReport(report) {}
~NewTraceReport();
NewTraceReport(const NewTraceReport& new_report) = delete;
NewTraceReport(NewTraceReport&& new_report) = default;
NewTraceReport& operator=(const NewTraceReport& new_report) = delete;
NewTraceReport& operator=(NewTraceReport&& new_report) = default;
// The serialized trace report content.
std::string trace_content;
// The serialized system profile information.
std::string system_profile;
};
// ClientTraceReport represents all metadata of a trace report to be displayed
// to user. Proto member is not included here since it can be of significant
// size. Therefore, if proto is needed it can be obtained through
// GetProtoValue().
struct CONTENT_EXPORT ClientTraceReport : BaseTraceReport {
ClientTraceReport();
~ClientTraceReport();
// The current upload state for this report represented by
// ReportUploadState.
ReportUploadState upload_state = ReportUploadState::kNotUploaded;
// The time at which the report was successfully uploaded to a server.
base::Time upload_time;
// Whether the report has content (payload) attached to it.
bool has_trace_content = false;
};
class CONTENT_EXPORT TraceReportDatabase {
public:
TraceReportDatabase();
~TraceReportDatabase() = default;
TraceReportDatabase(const TraceReportDatabase&) = delete;
TraceReportDatabase& operator=(const TraceReportDatabase&) = delete;
bool is_open() const { return database_.is_open(); }
bool is_initialized() const { return initialized_; }
bool OpenDatabase(const base::FilePath& path);
// Open database only if it already exists.
bool OpenDatabaseIfExists(const base::FilePath& path);
// Initialize DB and open in it memory.
bool OpenDatabaseInMemoryForTesting();
// Adds a new row (trace) to the local_traces table.
bool AddTrace(const NewTraceReport& new_report);
// Delete a row (trace) from the local_traces table.
bool DeleteTrace(const base::Token& uuid);
// Deletes all rows (traces) from the local_traces.
bool DeleteAllTraces();
// Delete traces between the |start| and |end| dates inclusively.
bool DeleteTracesInDateRange(base::Time start, base::Time end);
// Delete all reports older than |age| from today.
bool DeleteTraceReportsOlderThan(base::TimeDelta age);
// Delete uploaded trace content older than |age| from today.
bool DeleteUploadedTraceContentOlderThan(base::TimeDelta age);
// Delete old trace content, keeping up to `max_traces`.
bool DeleteOldTraceContent(size_t max_traces);
// Mark all reports that are pending upload as skipped with `skip_reason`.
bool AllPendingUploadSkipped(SkipUploadReason skip_reason);
bool UserRequestedUpload(const base::Token& uuid);
bool UploadComplete(const base::Token& uuid, base::Time time);
bool UploadSkipped(const base::Token& uuid, SkipUploadReason skip_reason);
// Returns the serialized trace content string if any.
std::optional<std::string> GetTraceContent(const base::Token& uuid);
// Returns the serialize system profile information if any.
std::optional<std::string> GetSystemProfile(const base::Token& uuid);
// Returns the number of trace for |scenario_name| since |since|.
std::optional<size_t> UploadCountSince(const std::string& scenario_name,
const std::string& upload_rule_name,
base::Time since);
// Returns the saved count per scenario since `since`.
base::flat_map<std::string, size_t> GetScenarioCountsSince(base::Time since);
// Returns all the reports currently stored in the database.
std::vector<ClientTraceReport> GetAllReports();
// Returns the next report pending upload.
std::optional<ClientTraceReport> GetNextReportPendingUpload();
private:
bool EnsureTableCreated();
sql::Database database_;
base::FilePath db_file_path_;
bool initialized_ = false;
// Guards usage of |database_|
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace content
#endif // CONTENT_BROWSER_TRACING_TRACE_REPORT_TRACE_REPORT_DATABASE_H_
|