CMS 3D CMS Logo

DQMFileSaverOnline.cc
Go to the documentation of this file.
12 #include "DQMFileSaverOnline.h"
13 
14 #include <TString.h>
15 #include <TSystem.h>
16 #include <sys/stat.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19 #include <fstream>
20 #include <iostream>
21 #include <string>
22 #include <utility>
23 #include <vector>
24 
25 #include <filesystem>
26 #include <boost/iostreams/device/mapped_file.hpp>
27 
28 using namespace dqm;
29 
31  backupLumiCount_ = ps.getUntrackedParameter<int>("backupLumiCount", 1);
32  keepBackupLumi_ = ps.getUntrackedParameter<bool>("keepBackupLumi", false);
33 }
34 
36 
38  if (backupLumiCount_ > 0) {
39  if (fp.lumi_ % backupLumiCount_ == 0) {
40  // actual saving is done here
41  makeSnapshot(fp, false);
42  }
43  }
44 }
45 
47 
48 void DQMFileSaverOnline::makeSnapshot(const FileParameters& fp, bool final) const {
49  int pid = getpid();
50  char hostname[64];
51  gethostname(hostname, 64);
52  hostname[63] = 0;
53 
54  char suffix[128];
55  if (!final) {
56  snprintf(suffix, 127, ".ls%08ld_host%s_pid%08d", fp.lumi_, hostname, pid);
57  } else {
58  suffix[0] = 0;
59  }
60 
61  std::string prefix = filename(fp, false);
62 
63  std::string root_fp = prefix + ".root" + suffix;
64  std::string meta_fp = prefix + ".root.origin" + suffix;
65 
66  std::string tmp_root_fp = root_fp + ".tmp";
67  std::string tmp_meta_fp = meta_fp + ".tmp";
68 
69  // run_ and lumi_ are ignored if dqmstore is not in multithread mode
71 
72  logFileAction("Writing DQM Root file: ", root_fp);
73  // logFileAction("Writing DQM Origin file: ", meta_fp);
74 
75  //char rewrite[128];
76  //snprintf(rewrite, 128, "\\1Run %ld/\\2/Run summary", fp.run_);
77 
78  //store->save(tmp_root_fp, /* filename */
79  // "", /* path */
80  // "^(Reference/)?([^/]+)", /* pattern */
81  // rewrite, /* rewrite */
82  // store->mtEnabled() ? fp.run_ : 0, /* run */
83  // 0, /* lumi */
84  // fp.saveReference_, /* ref */
85  // fp.saveReferenceQMin_, /* ref minStatus */
86  // "RECREATE"); /* fileupdate */
87  // TODO: some parameters prepared here are now unused, and the code should
88  // eventually be removed.
89  LegacyIOHelper h(&*store);
90  h.save(tmp_root_fp, "", fp.run_, /* saveall */ true, "RECREATE");
91 
92  // write metadata
93  // format.origin: md5:d566a34b27f48d507150a332b189398b 294835
94  // /home/dqmprolocal/output/DQM_V0001_FED_R000194224.root
95  std::ofstream meta_fd(tmp_meta_fp);
96  meta_fd << fillOrigin(tmp_root_fp, root_fp);
97  meta_fd.close();
98 
99  checkError("Rename failed: ", root_fp, ::rename(tmp_root_fp.c_str(), root_fp.c_str()));
100  checkError("Rename failed: ", meta_fp, ::rename(tmp_meta_fp.c_str(), meta_fp.c_str()));
101 
102  SnapshotFiles files = {root_fp, meta_fp};
103  if (final) {
104  // final will never be cleared
106 
107  saveJobReport(root_fp);
108  } else {
109  appendSnapshot(SnapshotFiles{root_fp, meta_fp});
110  }
111 }
112 
114  std::lock_guard<std::mutex> lock(snapshots_lock_);
115 
116  if (!keepBackupLumi_) {
117  while (!snapshots_.empty()) {
118  SnapshotFiles& x = snapshots_.front();
119 
120  // logFileAction("Deleting old snapshot (origin): ", x.meta);
121  checkError("Unlink failed: ", x.meta, ::unlink(x.meta.c_str()));
122 
123  logFileAction("Deleting old snapshot (root): ", x.data);
124  checkError("Unlink failed: ", x.data, ::unlink(x.data.c_str()));
125 
126  snapshots_.pop_front();
127  }
128  }
129 
130  if (!f.data.empty()) {
131  snapshots_.push_back(f);
132  }
133 }
134 
135 void DQMFileSaverOnline::checkError(const char* msg, const std::string& file, int status) const {
136  if (status != 0) {
137  std::string actual_msg = msg;
138  actual_msg += std::strerror(status);
139  logFileAction(actual_msg, file);
140  }
141 }
142 
144  // format.origin (one line):
145  // md5:d566a34b27f48d507150a332b189398b 294835 final_filename.root
146 
148  EVP_MD_CTX* mdctx = EVP_MD_CTX_new();
149  const EVP_MD* md = EVP_get_digestbyname("MD5");
150  unsigned int md_len = 0;
151  unsigned char md5[EVP_MAX_MD_SIZE];
152 
153  boost::iostreams::mapped_file_source fp(filename);
154 
155  EVP_DigestInit_ex(mdctx, md, nullptr);
156  EVP_DigestUpdate(mdctx, (unsigned char*)fp.data(), fp.size());
157  EVP_DigestFinal_ex(mdctx, md5, &md_len);
158  EVP_MD_CTX_free(mdctx);
159 
160  std::ostringstream hash;
161  for (unsigned int i = 0; i < md_len; i++) {
162  hash << std::hex << std::setfill('0') << std::setw(2) << (int)md5[i];
163  }
164 
165  std::ostringstream out;
166  out << "md5:" << hash.str() << " " << fp.size() << " " << final_filename;
167  return out.str();
168 }
169 
172  desc.setComment("Saves histograms from DQM store, online workflow.");
173 
174  desc.addUntracked<int>("backupLumiCount", 10)
175  ->setComment(
176  "How often the backup file will be generated, in lumisections (-1 "
177  "disables).");
178 
179  desc.addUntracked<bool>("keepBackupLumi", false)
180  ->setComment(
181  "Usually the backup old backup is deleted once the new file is "
182  "available. Setting this to true ensures that no backup files are "
183  "ever deleted. Useful for ML applications, which use backups as a "
184  "'history' of what happened during the run.");
185 
187 
188  // Changed to use addDefault instead of add here because previously
189  // DQMFileSaverOnline and DQMFileSaverPB both used the module label
190  // "saver" which caused conflicting cfi filenames to be generated.
191  // add could be used if unique module labels were given.
192  descriptions.addDefault(desc);
193 }
194 
void openssl_init()
Definition: openssl_init.cc:5
void logFileAction(const std::string &msg, const std::string &fileName) const
Definition: rename.py:1
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static const std::string fillOrigin(const std::string &filename, const std::string &final_filename)
static const std::string filename(const FileParameters &fp, bool useLumi=false)
#define EVP_MD_CTX_free
Definition: openssl_init.h:7
void saveJobReport(const std::string &filename) const
T getUntrackedParameter(std::string const &, T const &) const
void appendSnapshot(SnapshotFiles new_snap) const
void checkError(const char *msg, const std::string &file, int status) const
void addDefault(ParameterSetDescription const &psetDescription)
~DQMFileSaverOnline() override
#define EVP_MD_CTX_new
Definition: openssl_init.h:6
double f[11][100]
std::list< SnapshotFiles > snapshots_
void saveRun(const FileParameters &fp) const override
tuple msg
Definition: mps_check.py:285
void makeSnapshot(const FileParameters &fp, bool final) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
float x
static void fillDescription(edm::ParameterSetDescription &d)
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
Definition: DQMStore.h:18
DQMFileSaverOnline(const edm::ParameterSet &ps)
void saveLumi(const FileParameters &fp) const override