CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DQMMonitoringService.cc
Go to the documentation of this file.
1 #include "DQMMonitoringService.h"
2 
3 #include <boost/algorithm/string.hpp>
4 
5 #include <ctime>
6 
7 /*
8  * This service is very similar to the FastMonitoringService in the HLT,
9  * except that it is used for monitoring online DQM applications
10  */
11 
12 namespace dqmservices {
13 
14 namespace fs = boost::filesystem;
15 
16 #define MAX_LOG_SIZE 64*1024
17 
19  json_path_ = pset.getUntrackedParameter<std::string>("jsonPath");
20 
21  char host[128];
22  if (gethostname(host ,sizeof(host)) == -1) {
23  throw cms::Exception("DQMMonitoringService")
24  << "Internal error, cannot get host name";
25  }
26 
27  hostname_ = host;
28  fseq_ = 0;
29  tag_ = "";
30 
31  try {
33  } catch (...) {
34  // pass
35  }
36 }
37 
39 }
40 
42  extra_.put_child(name, data);
43 }
44 
46  try {
47  reportLumiSectionUnsafe(run, lumi);
48  } catch (...) {
49  // pass
50  }
51 }
52 
54  nevents_ += nevts;
55 }
56 
58  using std::chrono::duration_cast;
59  using std::chrono::milliseconds;
60 
61  int pid = getpid();
62  ++fseq_;
63 
64  if (! fs::is_directory(json_path_)) {
65  extra_.clear();
66  return; // no directory present, quit
67  }
68 
70 
71  // document unique id
72  std::string id =
73  str(boost::format("dqm-source-state-run%06d-host%s-pid%06d") % run % hostname_ % pid);
74 
75  // output jsn file
76  std::string path_id;
77 
78  // check for debug fn
79  if (fs::exists(json_path_ / ".debug")) {
80  path_id = str(boost::format("%d.%08d+%s.jsn") % std::time(NULL) % fseq_ % id);
81  } else {
82  path_id = id + ".jsn";
83  }
84 
85  std::string tmp_path = (json_path_ / (path_id + ".tmp")).string();
86  std::string final_path = (json_path_ / path_id).string();
87 
89  rate = rate / duration_cast<milliseconds>(now - last_report_time_).count();
90  rate = rate / 100;
91 
92  ptree pt;
93  pt.put("_id", id);
94  pt.put("pid", pid);
95  pt.put("tag", tag_);
96  pt.put("hostname", hostname_);
97  pt.put("sequence", fseq_);
98  pt.put("type", "dqm-source-state");
99  pt.put("run", run);
100  pt.put("lumi", lumi);
101 
102  pt.put("events_total", nevents_);
103  pt.put("events_rate", rate);
104 
105  // add some additional per-lumi information
107  pt.put("stderr", log);
108 
110 
111  // these are predefined
112  pt.add_child("extra", extra_);
113  pt.add_child("ps_info", ps_info_);
114 
115  std::ofstream file(tmp_path);
116  write_json(file, pt, true);
117  file.close();
118 
121 
122  rename(tmp_path.c_str(), final_path.c_str());
123 }
124 
126  int fd = open("/proc/self/cmdline", O_RDONLY);
127  ptree cmdline;
128 
129  if (fd != -1) {
130  unsigned char buf[1024];
131  int nbytesread = read(fd, buf, 1024);
132 
133  // make last character zero
134  // in case we have read less than buf
135  if (nbytesread > 0)
136  buf[nbytesread-1] = 0;
137 
138  unsigned char *end = buf + nbytesread;
139  for (unsigned char *p = buf; p < end; ) {
140  std::string token((char *)p);
141  ptree child;
142  child.put("", token);
143  cmdline.push_back(std::make_pair("", child));
144 
145  if ((tag_.size() == 0) &&
146  (token.find(".py") != std::string::npos)) {
147 
148  // a hack to set the tag until we figure
149  // out how to set it properly
150  tag_ = token;
151  boost::replace_last(tag_, ".py", "");
152  boost::replace_last(tag_, "_cfg", "");
153  }
154 
155  while (*p++); // skip until start of next 0-terminated section
156  }
157  close(fd);
158  }
159 
160  ps_info_.put_child("cmdline", cmdline);
161 }
162 
164  ptree data;
165 
166  std::ifstream in("/proc/self/status");
168 
169  if (in) {
170  while (std::getline(in, line)) {
171  size_t pos = line.find(':');
172  if (pos == std::string::npos)
173  continue;
174 
175  std::string value = line.substr(pos+1);
176  boost::trim(value); // value
177  line.resize(pos); // key
178 
179  data.put(line, value);
180  }
181 
182  in.close();
183  }
184 
185  ps_info_.put_child("status", data);
186 }
187 
189  // magic
190  char buf[MAX_LOG_SIZE + 1];
191  ssize_t ret = readlink("/proc/self/fd/2", buf, MAX_LOG_SIZE);
192  if (ret > 0) {
193  buf[ret] = 0;
194  } else {
195  return "error: can't read the stderr link.";
196  }
197 
198  if (strstr(buf, "/dev/") != NULL) {
199  // can't read this weird file
200  return "error: stderr is a special file.";
201  }
202 
203  // try to open
204  FILE *sr = fopen(buf , "rb");
205  if (sr == NULL)
206  return "error: can't open the stderr (deleted?).";
207 
208  // try to get the last position
209  // if this is an ordinary it will succeed
210  fseek(sr, 0, SEEK_END);
211  long size = ftell(sr);
212  if (size > 0) {
213  long from = size - (MAX_LOG_SIZE);
214  if (from < 0)
215  from = 0;
216 
217  fseek(sr, from, SEEK_SET);
218  size_t read = fread(buf, 1, MAX_LOG_SIZE, sr);
219  buf[read] = 0;
220 
221  // If "from" was not zero, discard the first line.
222  // Since it will be corrupted anyway.
223  char *start = buf;
224 
225  if (from != 0) {
226  start = strchr(start, '\n');
227  if (start == NULL) {
228  // should not happen
229  // return an empty string
230  start = buf + read;
231  } else {
232  start = start + 1;
233  }
234  }
235 
236  return std::string(start);
237  }
238 
239  fclose(sr);
240  return "error: stderr is not a seek-able file.";
241 }
242 
243 } // end-of-namespace
244 
246 
T getUntrackedParameter(std::string const &, T const &) const
tuple start
Check for commandline option errors.
Definition: dqm_diff.py:58
tuple lumi
Definition: fjr2json.py:35
#define NULL
Definition: scimark2.h:8
void registerExtra(std::string name, ptree data)
string format
Some error handling for the usage.
#define MAX_LOG_SIZE
void reportLumiSection(int run, int lumi)
#define end
Definition: vmac.h:37
#define DEFINE_FWK_SERVICE(type)
Definition: ServiceMaker.h:113
string host
Definition: query.py:114
std::chrono::high_resolution_clock::time_point last_report_time_
tuple pid
Definition: sysUtil.py:22
void reportLumiSectionUnsafe(int run, int lumi)
double rate(double x)
Definition: Constants.cc:3
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
DQMMonitoringService(const edm::ParameterSet &, edm::ActivityRegistry &)
int nevts
Definition: jetmet_cfg.py:3
tuple size
Write out results.