62 Lookup(
"publish.revision")->ToString()),
63 files_added(statistics->
64 Lookup(
"publish.n_files_added")->ToString()),
65 files_removed(statistics->
66 Lookup(
"publish.n_files_removed")->ToString()),
67 files_changed(statistics->
68 Lookup(
"publish.n_files_changed")->ToString()),
69 chunks_added(statistics->
70 Lookup(
"publish.n_chunks_added")->ToString()),
71 chunks_duplicated(statistics->
72 Lookup(
"publish.n_chunks_duplicated")->ToString()),
73 catalogs_added(statistics->
74 Lookup(
"publish.n_catalogs_added")->ToString()),
75 dirs_added(statistics->
76 Lookup(
"publish.n_directories_added")->ToString()),
77 dirs_removed(statistics->
78 Lookup(
"publish.n_directories_removed")->ToString()),
79 dirs_changed(statistics->
80 Lookup(
"publish.n_directories_changed")->ToString()),
81 symlinks_added(statistics->
82 Lookup(
"publish.n_symlinks_added")->ToString()),
83 symlinks_removed(statistics->
84 Lookup(
"publish.n_symlinks_removed")->ToString()),
85 symlinks_changed(statistics->
86 Lookup(
"publish.n_symlinks_changed")->ToString()),
87 bytes_added(statistics->
88 Lookup(
"publish.sz_added_bytes")->ToString()),
89 bytes_removed(statistics->
90 Lookup(
"publish.sz_removed_bytes")->ToString()),
91 bytes_uploaded(statistics->
92 Lookup(
"publish.sz_uploaded_bytes")->ToString()),
93 catalog_bytes_uploaded(statistics->
94 Lookup(
"publish.sz_uploaded_catalog_bytes")->ToString()) {
108 c = statistics->
Lookup(
"gc.n_preserved_catalogs");
109 n_preserved_catalogs = c ? c->
ToString() :
"0";
110 c = statistics->
Lookup(
"gc.n_condemned_catalogs");
111 n_condemned_catalogs = c ? c->
ToString() :
"0";
112 c = statistics->
Lookup(
"gc.n_condemned_objects");
113 n_condemned_objects = c ? c->
ToString() :
"0";
114 c = statistics->
Lookup(
"gc.sz_condemned_bytes");
115 sz_condemned_bytes = c ? c->
ToString() :
"0";
116 c = statistics->
Lookup(
"gc.n_duplicate_delete_requests");
117 n_duplicate_delete_requests = c ? c->
ToString() :
"0";
129 const std::string &start_time,
130 const std::string &finish_time,
131 const bool success) {
133 std::string insert_statement =
134 "INSERT INTO publish_statistics ("
145 "directories_removed,"
146 "directories_changed,"
153 "sz_catalog_bytes_uploaded,"
157 "'"+finish_time+
"',"+
175 (success ?
"1" :
"0") +
");";
176 return insert_statement;
190 const std::string &start_time,
191 const std::string &finish_time,
192 const std::string &repo_name,
193 const bool success) {
195 std::string insert_statement =
"";
198 "INSERT INTO gc_statistics ("
201 "n_preserved_catalogs,"
202 "n_condemned_catalogs,"
203 "n_condemned_objects,"
204 "sz_condemned_bytes,"
205 "n_duplicate_delete_requests,"
208 "'" + start_time +
"'," +
209 "'" + finish_time +
"'," +
215 (success ?
"1" :
"0") +
");";
219 "INSERT INTO gc_statistics ("
222 "n_preserved_catalogs,"
223 "n_condemned_catalogs,"
224 "n_condemned_objects,"
225 "n_duplicate_delete_requests,"
228 "'" + start_time +
"'," +
229 "'" + finish_time +
"'," +
234 (success ?
"1" :
"0") +
");";
236 return insert_statement;
245 "CREATE TABLE publish_statistics ("
246 "publish_id INTEGER PRIMARY KEY,"
250 "files_added INTEGER,"
251 "files_removed INTEGER,"
252 "files_changed INTEGER,"
253 "chunks_added INTEGER,"
254 "chunks_duplicated INTEGER,"
255 "catalogs_added INTEGER,"
256 "directories_added INTEGER,"
257 "directories_removed INTEGER,"
258 "directories_changed INTEGER,"
259 "symlinks_added INTEGER,"
260 "symlinks_removed INTEGER,"
261 "symlinks_changed INTEGER,"
262 "sz_bytes_added INTEGER,"
263 "sz_bytes_removed INTEGER,"
264 "sz_bytes_uploaded INTEGER,"
265 "sz_catalog_bytes_uploaded INTEGER,"
266 "success INTEGER);").
Execute();
268 "CREATE TABLE gc_statistics ("
269 "gc_id INTEGER PRIMARY KEY,"
272 "n_preserved_catalogs INTEGER,"
273 "n_condemned_catalogs INTEGER,"
274 "n_condemned_objects INTEGER,"
275 "sz_condemned_bytes INTEGER,"
276 "n_duplicate_delete_requests INTEGER,"
277 "success INTEGER);").
Execute();
294 "statistics database");
297 "publish_statistics RENAME COLUMN finished_time TO finish_time;");
299 "publish_statistics ADD revision INTEGER;");
301 "publish_statistics RENAME COLUMN duplicated_files TO chunks_duplicated;");
303 "publish_statistics ADD chunks_added INTEGER;");
305 "publish_statistics ADD symlinks_added INTEGER;");
307 "publish_statistics ADD symlinks_removed INTEGER;");
309 "publish_statistics ADD symlinks_changed INTEGER;");
311 "publish_statistics ADD catalogs_added INTEGER;");
313 "publish_statistics ADD sz_catalog_bytes_uploaded INTEGER;");
315 if (!publish_upgrade2_1.
Execute() ||
316 !publish_upgrade2_2.
Execute() ||
317 !publish_upgrade2_3.
Execute() ||
318 !publish_upgrade2_4.
Execute() ||
319 !publish_upgrade2_5.
Execute() ||
320 !publish_upgrade2_6.
Execute() ||
321 !publish_upgrade2_7.
Execute() ||
322 !publish_upgrade2_8.
Execute() ||
323 !publish_upgrade2_9.
Execute()) {
325 " table of statistics database");
330 " RENAME COLUMN finished_time TO finish_time;");
332 if (!gc_upgrade2_1.
Execute()) {
334 " table of statistics database");
341 " of statistics database");
349 "statistics database");
352 "publish_statistics ADD success INTEGER;");
354 if (!publish_upgrade3_1.
Execute()) {
356 " table of statistics database");
361 " ADD success INTEGER;");
363 if (!gc_upgrade3_1.
Execute()) {
365 " table of statistics database");
372 " of statistics database");
380 "statistics database");
383 " ADD n_duplicate_delete_requests INTEGER;");
385 if (!gc_upgrade4_1.
Execute()) {
387 "table of statistics database");
394 "of statistics database");
414 const std::string repo_name)
417 std::string db_file_path;
418 uint32_t days_to_keep;
419 GetDBParams(repo_name, &db_file_path, &days_to_keep);
424 }
else if (db->
GetProperty<std::string>(
"repo_name") != repo_name) {
426 "is incorrect. Please fix the database.", db_file_path.c_str());
428 if (!db->
Prune(days_to_keep)) {
436 }
else if (!db->
SetProperty(
"repo_name", repo_name)) {
438 "Couldn't insert repo_name into properties table!");
448 const std::string &start_time,
453 finish_time, success);
460 const std::string &start_time,
464 std::string statement =
476 "Couldn't store statistics in %s: insert.Execute failed!",
488 if (days == 0)
return true;
490 std::string publish_stmt =
491 "DELETE FROM publish_statistics WHERE "
492 "julianday('now','start of day')-julianday(start_time) > " +
495 std::string gc_stmt =
496 "DELETE FROM gc_statistics WHERE "
497 "julianday('now','start of day')-julianday(start_time) > " +
504 "Couldn't prune statistics DB %s: SQL Execute() failed!",
510 "Couldn't prune statistics DB %s: Vacuum() failed!",
520 std::string local_path)
522 if (local_path ==
"") {
526 spooler->WaitForUpload();
527 unsigned errors_before = spooler->GetNumberOfErrors();
528 spooler->Mkdir(
"stats");
529 spooler->RemoveAsync(
"stats/stats.db");
530 spooler->WaitForUpload();
531 spooler->Upload(local_path,
"stats/stats.db");
532 spooler->WaitForUpload();
533 unsigned errors_after = spooler->GetNumberOfErrors();
535 if (errors_before != errors_after) {
537 "Could not upload statistics DB file into storage backend");
546 std::string local_path)
548 if (local_path ==
"") {
557 uploader->
UploadFile(local_path,
"stats/stats.db");
560 return errors_before == errors_after;
566 uint32_t *days_to_keep)
569 const std::string db_default_path =
570 "/var/spool/cvmfs/" + repo_name +
"/stats.db";
571 const std::string repo_config_file =
572 "/etc/cvmfs/repositories.d/" + repo_name +
"/server.conf";
577 "Could not parse repository configuration: %s.",
578 repo_config_file.c_str());
579 *path = db_default_path;
584 std::string statistics_db =
"";
585 if (!parser.
GetValue(
"CVMFS_STATISTICS_DB", &statistics_db)) {
587 "Parameter %s was not set in the repository configuration file. "
588 "Using default value: %s",
589 "CVMFS_STATISTICS_DB", db_default_path.c_str());
590 *path = db_default_path;
593 int mode = S_IRUSR | S_IWUSR | S_IXUSR |
594 S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
597 "Couldn't write statistics at the specified path %s.",
598 statistics_db.c_str());
599 *path = db_default_path;
601 *path = statistics_db;
605 std::string days_to_keep_str =
"";
606 if (!parser.
GetValue(
"CVMFS_STATS_DB_DAYS_TO_KEEP", &statistics_db)) {
608 "Parameter %s was not set in the repository configuration file. "
609 "Using default value: %s",
610 "CVMFS_STATS_DB_DAYS_TO_KEEP",
614 *days_to_keep =
static_cast<uint32_t
> (
String2Uint64(days_to_keep_str));
627 std::string param_value =
"";
628 const std::string repo_config_file =
629 "/etc/cvmfs/repositories.d/" + repo_name +
"/server.conf";
633 "Could not parse repository configuration: %s.",
634 repo_config_file.c_str());
637 if (!parser.
GetValue(
"CVMFS_EXTENDED_GC_STATS", ¶m_value)) {
639 "Parameter %s was not set in the repository configuration file. "
640 "condemned_bytes were not counted.",
641 "CVMFS_EXTENDED_GC_STATS");
642 }
else if (parser.
IsOn(param_value)) {
652 create_empty_db_calls(0), check_compatibility_calls(0),
653 live_upgrade_calls(0), compact_calls(0)
virtual void WaitForUpload() const
std::string chunks_duplicated
StatisticsDatabase(const std::string &filename, const OpenMode open_mode)
std::string n_condemned_objects
std::string sz_condemned_bytes
std::string symlinks_changed
std::string GetGMTimestamp(const std::string &format)
std::string PrepareStatementIntoGc(const perf::Statistics *statistics, const std::string &start_time, const std::string &finish_time, const std::string &repo_name, const bool success)
const std::string & filename() const
bool UploadStatistics(upload::Spooler *spooler, std::string local_path="")
bool StoreGCStatistics(const perf::Statistics *statistics, const std::string &start_time, const bool success)
std::string catalog_bytes_uploaded
static unsigned int instances
bool IsOn(const std::string ¶m_value) const
std::string catalogs_added
bool CreateEmptyDatabase()
std::string symlinks_removed
unsigned int live_upgrade_calls
float schema_version() const
bool Prune(uint32_t days)
upload::Spooler * spooler
PublishStats(const perf::Statistics *statistics)
std::string StringifyUint(const uint64_t value)
void set_schema_revision(const unsigned rev)
std::string PrepareStatementIntoPublish(const perf::Statistics *statistics, const std::string &start_time, const std::string &finish_time, const bool success)
static StatisticsDatabase * Open(const std::string &filename, const OpenMode open_mode)
T GetProperty(const std::string &key) const
unsigned schema_revision() const
std::string n_condemned_catalogs
bool LiveSchemaUpgradeIfNecessary()
std::string bytes_uploaded
static bool compacting_fails
bool FileExists(const std::string &path)
Counter * Lookup(const std::string &name) const
bool TryParsePath(const std::string &config_file)
std::string symlinks_added
static const float kLatestCompatibleSchema
std::string files_changed
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
unsigned int create_empty_db_calls
static float kLatestSchema
std::string files_removed
sqlite3 * sqlite_db() const
unsigned int check_compatibility_calls
static unsigned kLatestSchemaRevision
std::string n_duplicate_delete_requests
bool GetValue(const std::string &key, std::string *value) const
virtual unsigned int GetNumberOfErrors() const =0
static StatisticsDatabase * OpenStandardDB(const std::string repo_name)
bool SetProperty(const std::string &key, const T value)
std::string bytes_removed
static bool GcExtendedStats(const std::string &repo_name)
bool StoreEntry(const std::string &insert_statement)
void UploadFile(const std::string &local_path, const std::string &remote_path, const CallbackTN *callback=NULL)
bool StorePublishStatistics(const perf::Statistics *statistics, const std::string &start_time, const bool success)
static const uint32_t kDefaultDaysToKeep
bool IsEqualSchema(const float value, const float compare) const
uint64_t String2Uint64(const string &value)
unsigned int compact_calls
void RemoveAsync(const std::string &file_to_delete)
PathString GetParentPath(const PathString &path)
std::string n_preserved_catalogs
GcStats(const perf::Statistics *statistics)
bool StoreSchemaRevision()
bool CheckSchemaCompatibility()
static void GetDBParams(const std::string &repo_name, std::string *path, uint32_t *days_to_keep)
static StatisticsDatabase * Create(const std::string &filename)
bool CompactDatabase() const
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)