CernVM-FS  2.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
statistics_database.cc
Go to the documentation of this file.
1 
5 #include "statistics_database.h"
6 
7 #include "util/exception.h"
8 
9 
12 
13 // Changelog
14 // 1 --> 2: (Sep 4 2019)
15 // * change column name `finished_time` -> `finish_time`
16 // in publish_statistics table
17 // * add column `revision` to publish_statistics table
18 // * change column name `duplicated_files` -> `chunks_duplicated`
19 // in publish_statistics table
20 // * add column `chunks_added` to publish_statistics table
21 // * add column `symlinks_added` to publish_statistics table
22 // * add column `symlinks_removed` to publish_statistics table
23 // * add column `symlinks_changed` to publish_statistics table
24 // * change column name `finished_time` -> `finish_time`
25 // in gc_statistics table
26 // 2 --> 3: (Jan 14 2020)
27 // * add `success` column to publish_statistics table (1 for success
28 // 0 for fail)
29 // * add `success` column to gc_statistics table (1 for success
30 // 0 for fail)
31 // 3 --> 4: (Feb 1 2022)
32 // * add column `n_duplicate_delete_requests` to gc_statistics table
33 
35 unsigned int StatisticsDatabase::instances = 0;
37 
38 
39 namespace {
40 
41 struct PublishStats {
42  std::string revision;
43  std::string files_added;
44  std::string files_removed;
45  std::string files_changed;
46  std::string chunks_added;
47  std::string chunks_duplicated;
48  std::string catalogs_added;
49  std::string dirs_added;
50  std::string dirs_removed;
51  std::string dirs_changed;
52  std::string symlinks_added;
53  std::string symlinks_removed;
54  std::string symlinks_changed;
55  std::string bytes_added;
56  std::string bytes_removed;
57  std::string bytes_uploaded;
59 
60  explicit PublishStats(const perf::Statistics *statistics):
61  revision(statistics->
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()) {
95  }
96 };
97 
98 
99 struct GcStats {
100  std::string n_preserved_catalogs;
101  std::string n_condemned_catalogs;
102  std::string n_condemned_objects;
103  std::string sz_condemned_bytes;
105 
106  explicit GcStats(const perf::Statistics *statistics) {
107  perf::Counter *c = NULL;
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";
118  }
119 };
120 
121 
128 std::string PrepareStatementIntoPublish(const perf::Statistics *statistics,
129  const std::string &start_time,
130  const std::string &finish_time,
131  const bool success) {
132  struct PublishStats stats = PublishStats(statistics);
133  std::string insert_statement =
134  "INSERT INTO publish_statistics ("
135  "start_time,"
136  "finish_time,"
137  "revision,"
138  "files_added,"
139  "files_removed,"
140  "files_changed,"
141  "chunks_added,"
142  "chunks_duplicated,"
143  "catalogs_added,"
144  "directories_added,"
145  "directories_removed,"
146  "directories_changed,"
147  "symlinks_added,"
148  "symlinks_removed,"
149  "symlinks_changed,"
150  "sz_bytes_added,"
151  "sz_bytes_removed,"
152  "sz_bytes_uploaded,"
153  "sz_catalog_bytes_uploaded,"
154  "success)"
155  " VALUES("
156  "'"+start_time+"',"+
157  "'"+finish_time+"',"+
158  stats.revision+"," +
159  stats.files_added+"," +
160  stats.files_removed +","+
161  stats.files_changed + "," +
162  stats.chunks_added + "," +
163  stats.chunks_duplicated + "," +
164  stats.catalogs_added + "," +
165  stats.dirs_added + "," +
166  stats.dirs_removed + "," +
167  stats.dirs_changed + "," +
168  stats.symlinks_added + "," +
169  stats.symlinks_removed + "," +
170  stats.symlinks_changed + "," +
171  stats.bytes_added + "," +
172  stats.bytes_removed + "," +
173  stats.bytes_uploaded + "," +
174  stats.catalog_bytes_uploaded + "," +
175  (success ? "1" : "0") + ");";
176  return insert_statement;
177 }
178 
179 
189 std::string PrepareStatementIntoGc(const perf::Statistics *statistics,
190  const std::string &start_time,
191  const std::string &finish_time,
192  const std::string &repo_name,
193  const bool success) {
194  struct GcStats stats = GcStats(statistics);
195  std::string insert_statement = "";
196  if (StatisticsDatabase::GcExtendedStats(repo_name)) {
197  insert_statement =
198  "INSERT INTO gc_statistics ("
199  "start_time,"
200  "finish_time,"
201  "n_preserved_catalogs,"
202  "n_condemned_catalogs,"
203  "n_condemned_objects,"
204  "sz_condemned_bytes,"
205  "n_duplicate_delete_requests,"
206  "success)"
207  " VALUES("
208  "'" + start_time + "'," +
209  "'" + finish_time + "'," +
210  stats.n_preserved_catalogs + "," +
211  stats.n_condemned_catalogs + ","+
212  stats.n_condemned_objects + "," +
213  stats.sz_condemned_bytes + "," +
214  stats.n_duplicate_delete_requests + "," +
215  (success ? "1" : "0") + ");";
216  } else {
217  // insert values except sz_condemned_bytes
218  insert_statement =
219  "INSERT INTO gc_statistics ("
220  "start_time,"
221  "finish_time,"
222  "n_preserved_catalogs,"
223  "n_condemned_catalogs,"
224  "n_condemned_objects,"
225  "n_duplicate_delete_requests,"
226  "success)"
227  " VALUES("
228  "'" + start_time + "'," +
229  "'" + finish_time + "'," +
230  stats.n_preserved_catalogs + "," +
231  stats.n_condemned_catalogs + "," +
232  stats.n_condemned_objects + "," +
233  stats.n_duplicate_delete_requests + "," +
234  (success ? "1" : "0") + ");";
235  }
236  return insert_statement;
237 }
238 
239 } // namespace
240 
241 
244  bool ret1 = sqlite::Sql(sqlite_db(),
245  "CREATE TABLE publish_statistics ("
246  "publish_id INTEGER PRIMARY KEY,"
247  "start_time TEXT,"
248  "finish_time TEXT,"
249  "revision INTEGER,"
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();
267  bool ret2 = sqlite::Sql(sqlite_db(),
268  "CREATE TABLE gc_statistics ("
269  "gc_id INTEGER PRIMARY KEY,"
270  "start_time TEXT,"
271  "finish_time TEXT,"
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();
278  return ret1 & ret2;
279 }
280 
281 
284  return (schema_version() > kLatestCompatibleSchema - 0.1 &&
286 }
287 
288 
292  (schema_revision() == 1)) {
293  LogCvmfs(kLogCvmfs, kLogDebug, "upgrading schema revision (1 --> 2) of "
294  "statistics database");
295 
296  sqlite::Sql publish_upgrade2_1(this->sqlite_db(), "ALTER TABLE "
297  "publish_statistics RENAME COLUMN finished_time TO finish_time;");
298  sqlite::Sql publish_upgrade2_2(this->sqlite_db(), "ALTER TABLE "
299  "publish_statistics ADD revision INTEGER;");
300  sqlite::Sql publish_upgrade2_3(this->sqlite_db(), "ALTER TABLE "
301  "publish_statistics RENAME COLUMN duplicated_files TO chunks_duplicated;");
302  sqlite::Sql publish_upgrade2_4(this->sqlite_db(), "ALTER TABLE "
303  "publish_statistics ADD chunks_added INTEGER;");
304  sqlite::Sql publish_upgrade2_5(this->sqlite_db(), "ALTER TABLE "
305  "publish_statistics ADD symlinks_added INTEGER;");
306  sqlite::Sql publish_upgrade2_6(this->sqlite_db(), "ALTER TABLE "
307  "publish_statistics ADD symlinks_removed INTEGER;");
308  sqlite::Sql publish_upgrade2_7(this->sqlite_db(), "ALTER TABLE "
309  "publish_statistics ADD symlinks_changed INTEGER;");
310  sqlite::Sql publish_upgrade2_8(this->sqlite_db(), "ALTER TABLE "
311  "publish_statistics ADD catalogs_added INTEGER;");
312  sqlite::Sql publish_upgrade2_9(this->sqlite_db(), "ALTER TABLE "
313  "publish_statistics ADD sz_catalog_bytes_uploaded INTEGER;");
314 
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()) {
324  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade publish_statistics"
325  " table of statistics database");
326  return false;
327  }
328 
329  sqlite::Sql gc_upgrade2_1(this->sqlite_db(), "ALTER TABLE gc_statistics"
330  " RENAME COLUMN finished_time TO finish_time;");
331 
332  if (!gc_upgrade2_1.Execute()) {
333  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade gc_statistics"
334  " table of statistics database");
335  return false;
336  }
337 
339  if (!StoreSchemaRevision()) {
340  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade schema revision"
341  " of statistics database");
342  return false;
343  }
344  }
345 
347  (schema_revision() == 2)) {
348  LogCvmfs(kLogCvmfs, kLogDebug, "upgrading schema revision (2 --> 3) of "
349  "statistics database");
350 
351  sqlite::Sql publish_upgrade3_1(this->sqlite_db(), "ALTER TABLE "
352  "publish_statistics ADD success INTEGER;");
353 
354  if (!publish_upgrade3_1.Execute()) {
355  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade publish_statistics"
356  " table of statistics database");
357  return false;
358  }
359 
360  sqlite::Sql gc_upgrade3_1(this->sqlite_db(), "ALTER TABLE gc_statistics"
361  " ADD success INTEGER;");
362 
363  if (!gc_upgrade3_1.Execute()) {
364  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade gc_statistics"
365  " table of statistics database");
366  return false;
367  }
368 
370  if (!StoreSchemaRevision()) {
371  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade schema revision"
372  " of statistics database");
373  return false;
374  }
375  }
376 
378  (schema_revision() == 3)) {
379  LogCvmfs(kLogCvmfs, kLogDebug, "upgrading schema revision (3 --> 4) of "
380  "statistics database");
381 
382  sqlite::Sql gc_upgrade4_1(this->sqlite_db(), "ALTER TABLE gc_statistics"
383  " ADD n_duplicate_delete_requests INTEGER;");
384 
385  if (!gc_upgrade4_1.Execute()) {
386  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade gc_statistics "
387  "table of statistics database");
388  return false;
389  }
390 
392  if (!StoreSchemaRevision()) {
393  LogCvmfs(kLogCvmfs, kLogSyslogErr, "failed to upgrade schema revision "
394  "of statistics database");
395  return false;
396  }
397  }
398  return true;
399 }
400 
401 
403  ++compact_calls;
404  return !compacting_fails;
405 }
406 
407 
410 }
411 
412 
414  const std::string repo_name)
415 {
416  StatisticsDatabase *db;
417  std::string db_file_path;
418  uint32_t days_to_keep;
419  GetDBParams(repo_name, &db_file_path, &days_to_keep);
420  if (FileExists(db_file_path)) {
421  db = StatisticsDatabase::Open(db_file_path, kOpenReadWrite);
422  if (db == NULL) {
423  PANIC(kLogSyslogErr, "Couldn't create StatisticsDatabase object!");
424  } else if (db->GetProperty<std::string>("repo_name") != repo_name) {
425  PANIC(kLogSyslogErr, "'repo_name' property of the statistics database %s "
426  "is incorrect. Please fix the database.", db_file_path.c_str());
427  }
428  if (!db->Prune(days_to_keep)) {
429  LogCvmfs(kLogCvmfs, kLogSyslogErr, "Failed to prune statistics database");
430  }
431  } else {
432  db = StatisticsDatabase::Create(db_file_path);
433  if (db == NULL) {
434  PANIC(kLogSyslogErr, "Couldn't create StatisticsDatabase object!");
435  // insert repo_name into properties table
436  } else if (!db->SetProperty("repo_name", repo_name)) {
438  "Couldn't insert repo_name into properties table!");
439  }
440  }
441  db->repo_name_ = repo_name;
442  return db;
443 }
444 
445 
447  const perf::Statistics *statistics,
448  const std::string &start_time,
449  const bool success)
450 {
451  std::string finish_time = GetGMTimestamp();
452  std::string statement = PrepareStatementIntoPublish(statistics, start_time,
453  finish_time, success);
454  return StoreEntry(statement);
455 }
456 
457 
459  const perf::Statistics *statistics,
460  const std::string &start_time,
461  const bool success)
462 {
463  std::string finish_time = GetGMTimestamp();
464  std::string statement =
465  PrepareStatementIntoGc(statistics, start_time, finish_time,
466  repo_name_, success);
467  return StoreEntry(statement);
468 }
469 
470 
471 bool StatisticsDatabase::StoreEntry(const std::string &insert_statement) {
472  sqlite::Sql insert(this->sqlite_db(), insert_statement);
473 
474  if (!insert.Execute()) {
476  "Couldn't store statistics in %s: insert.Execute failed!",
477  this->filename().c_str());
478  return false;
479  }
480 
481  LogCvmfs(kLogCvmfs, kLogStdout, "Statistics stored at: %s",
482  this->filename().c_str());
483  return true;
484 }
485 
486 
487 bool StatisticsDatabase::Prune(uint32_t days) {
488  if (days == 0) return true;
489 
490  std::string publish_stmt =
491  "DELETE FROM publish_statistics WHERE "
492  "julianday('now','start of day')-julianday(start_time) > " +
493  StringifyUint(days) + ";";
494 
495  std::string gc_stmt =
496  "DELETE FROM gc_statistics WHERE "
497  "julianday('now','start of day')-julianday(start_time) > " +
498  StringifyUint(days) + ";";
499 
500  sqlite::Sql publish_sql(this->sqlite_db(), publish_stmt);
501  sqlite::Sql gc_sql(this->sqlite_db(), gc_stmt);
502  if (!publish_sql.Execute() || !gc_sql.Execute()) {
504  "Couldn't prune statistics DB %s: SQL Execute() failed!",
505  this->filename().c_str());
506  return false;
507  }
508  if (!this->Vacuum()) {
510  "Couldn't prune statistics DB %s: Vacuum() failed!",
511  this->filename().c_str());
512  return false;
513  }
514 
515  return true;
516 }
517 
518 
520  std::string local_path)
521 {
522  if (local_path == "") {
523  local_path = this->filename();
524  }
525 
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();
534 
535  if (errors_before != errors_after) {
537  "Could not upload statistics DB file into storage backend");
538  return false;
539  }
540  return true;
541 }
542 
543 
545  upload::AbstractUploader *uploader,
546  std::string local_path)
547 {
548  if (local_path == "") {
549  local_path = this->filename();
550  }
551 
552  uploader->WaitForUpload();
553  unsigned errors_before = uploader->GetNumberOfErrors();
554 
555  uploader->RemoveAsync("stats/stats.db");
556  uploader->WaitForUpload();
557  uploader->UploadFile(local_path, "stats/stats.db");
558  uploader->WaitForUpload();
559  unsigned errors_after = uploader->GetNumberOfErrors();
560  return errors_before == errors_after;
561 }
562 
563 
564 void StatisticsDatabase::GetDBParams(const std::string &repo_name,
565  std::string *path,
566  uint32_t *days_to_keep)
567 {
568  // default location
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";
573  SimpleOptionsParser parser;
574 
575  if (!parser.TryParsePath(repo_config_file)) {
577  "Could not parse repository configuration: %s.",
578  repo_config_file.c_str());
579  *path = db_default_path;
580  *days_to_keep = kDefaultDaysToKeep;
581  return;
582  }
583 
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;
591  } else {
592  std::string dirname = GetParentPath(statistics_db);
593  int mode = S_IRUSR | S_IWUSR | S_IXUSR |
594  S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; // 755
595  if (!MkdirDeep(dirname, mode, true)) {
597  "Couldn't write statistics at the specified path %s.",
598  statistics_db.c_str());
599  *path = db_default_path;
600  } else {
601  *path = statistics_db;
602  }
603  }
604 
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",
612  *days_to_keep = kDefaultDaysToKeep;
613  } else {
614  *days_to_keep = static_cast<uint32_t> (String2Uint64(days_to_keep_str));
615  }
616 }
617 
618 
625 bool StatisticsDatabase::GcExtendedStats(const std::string &repo_name) {
626  SimpleOptionsParser parser;
627  std::string param_value = "";
628  const std::string repo_config_file =
629  "/etc/cvmfs/repositories.d/" + repo_name + "/server.conf";
630 
631  if (!parser.TryParsePath(repo_config_file)) {
633  "Could not parse repository configuration: %s.",
634  repo_config_file.c_str());
635  return false;
636  }
637  if (!parser.GetValue("CVMFS_EXTENDED_GC_STATS", &param_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)) {
643  return true;
644  }
645  return false;
646 }
647 
648 
649 StatisticsDatabase::StatisticsDatabase(const std::string &filename,
650  const OpenMode open_mode) :
651  sqlite::Database<StatisticsDatabase>(filename, open_mode),
652  create_empty_db_calls(0), check_compatibility_calls(0),
653  live_upgrade_calls(0), compact_calls(0)
654 {
656 }
657 
658 const uint32_t StatisticsDatabase::kDefaultDaysToKeep = 365;
virtual void WaitForUpload() const
StatisticsDatabase(const std::string &filename, const OpenMode open_mode)
std::string ToString()
Definition: statistics.cc:24
bool Execute()
Definition: sql.cc:42
std::string GetGMTimestamp(const std::string &format)
Definition: string.cc:615
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
Definition: sql.h:148
bool UploadStatistics(upload::Spooler *spooler, std::string local_path="")
bool StoreGCStatistics(const perf::Statistics *statistics, const std::string &start_time, const bool success)
#define PANIC(...)
Definition: exception.h:29
static unsigned int instances
bool IsOn(const std::string &param_value) const
Definition: options.cc:409
unsigned int live_upgrade_calls
bool Prune(uint32_t days)
std::string StringifyUint(const uint64_t value)
Definition: string.cc:84
void set_schema_revision(const unsigned rev)
Definition: sql.h:253
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
Definition: sql_impl.h:305
unsigned schema_revision() const
Definition: sql.h:150
static bool compacting_fails
bool FileExists(const std::string &path)
Definition: posix.cc:791
Counter * Lookup(const std::string &name) const
Definition: statistics.cc:62
bool TryParsePath(const std::string &config_file)
Definition: options.cc:110
static const float kLatestCompatibleSchema
bool MkdirDeep(const std::string &path, const mode_t mode, bool verify_writable)
Definition: posix.cc:846
unsigned int create_empty_db_calls
static float kLatestSchema
sqlite3 * sqlite_db() const
Definition: sql.h:147
unsigned int check_compatibility_calls
static unsigned kLatestSchemaRevision
bool GetValue(const std::string &key, std::string *value) const
Definition: options.cc:376
virtual unsigned int GetNumberOfErrors() const =0
static StatisticsDatabase * OpenStandardDB(const std::string repo_name)
bool SetProperty(const std::string &key, const T value)
Definition: sql_impl.h:325
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
Definition: sql.h:131
uint64_t String2Uint64(const string &value)
Definition: string.cc:228
unsigned int compact_calls
void RemoveAsync(const std::string &file_to_delete)
PathString GetParentPath(const PathString &path)
Definition: shortstring.cc:15
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,...)
Definition: logging.cc:528